package org.keyintegrity.webbeans.metadata;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.keyintegrity.webbeans.utils.BeanUtils;

public abstract class BeanMetadata implements Serializable {

    private static final Logger logger = Logger.getLogger(BeanMetadata.class);
    
    protected String associatedClass;
    protected List<FieldMetadata> fieldsMetadata;
    
    protected abstract FieldMetadata newFieldMetadata();

    public FieldMetadata getMetadataForField(String fieldName) {
        for (FieldMetadata metadata : getFieldsMetadata()) {
            if (metadata.getFieldName().equals(fieldName)) {
                return metadata;
            }
        }
        return getDefaultFieldMetadata(fieldName);
    }
    
    /**
     * Bean fields metadata as an unmodifiable list
     * @see FieldMetadata
     */
    public List<FieldMetadata> getFieldsMetadata() {
        if (fieldsMetadata == null) {
            initFieldsMetadata();
        }
        return fieldsMetadata;
    }

    private void initFieldsMetadata() {
        try {
            List<String> fieldNames = BeanUtils.getBeanFieldNames(Class.forName(associatedClass));
            this.fieldsMetadata = new ArrayList<FieldMetadata>(fieldNames.size()); 
            for (String fieldName : fieldNames) {
                FieldMetadata fm = newFieldMetadata();
                fm.setFieldName(fieldName);
                fieldsMetadata.add(fm);
            }
        } catch (ClassNotFoundException e) {
            logger.error(e);
        }
    }
    
    /** Bean class to which this metadata applied */
    public String getAssociatedClass() {
        return associatedClass;
    }
    public void setAssociatedClass(String clazz) {
        this.associatedClass = clazz;
    }

    public static FieldMetadata getDefaultFieldMetadata(final String fieldName) {
        return //  Default field metadata
            new FieldMetadata() {
            
                /**
                 * 
                 */
                private static final long serialVersionUID = -1584978301789278986L;

                {
                    setFieldName(fieldName);
                    setReadOnly(false);
                    setAppearance(Appearance.BOTH);
                    setDisplayPattern(null);
                    setTypeParameter(null);
                    //  TODO (Placeholder) Update this code when FieldMedatata class changes
                }
            };
    }

}
